home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / mac / MacFull.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  12.1 KB  |  467 lines

  1. /*****************************************************************************
  2.     Full-Screen Access Demo
  3.     Macintosh DisplayManager 2.0 implementation
  4.  
  5.     This code is Copyright (c) 1996 by Jon Blossom. All Rights Reserved.
  6.  ****************************************************************************/
  7.  
  8. #ifndef _WINDOWS
  9.  
  10. //****************************************************************************
  11. // System includes
  12.  
  13. #include <QDOffscreen.h>
  14. #include <Video.h>
  15. #include <Displays.h>
  16. #include <Palettes.h>
  17. #include <Timer.h>
  18.  
  19. //****************************************************************************
  20. // Internal functions
  21.  
  22. void StealMenuBar(void);
  23. void RestoreMenuBar(void);
  24.  
  25. void DemoMain(void);
  26.  
  27. long unsigned GetMillisecondTime(void)
  28. {
  29.     // Get a microsecond-accurate time from the Time Manager
  30.     UnsignedWide Microsecs;
  31.     Microseconds(&Microsecs);
  32.  
  33.     // TODO: Do this right! And don't use doubles!
  34.     double Time;
  35.     Time = (double)Microsecs.hi * (double)0xFFFFFFFF;
  36.     Time = Time + (double)Microsecs.lo;
  37.     Time = Time / 1000.0;
  38.     while (Time > (double)0xFFFFFFFF)
  39.         Time = Time - (double)0xFFFFFFFF;
  40.     return (long unsigned)Time;
  41. }
  42.  
  43. //****************************************************************************
  44. // Internal globals
  45.  
  46. static WindowPtr Window =0;
  47. static PaletteHandle hPalette =0;
  48. static GWorldPtr pOffscreenGWorld =0;
  49. static GDHandle DisplayDevice;
  50.  
  51. static unsigned short csPreviousMode;
  52. static unsigned long csPreviousData;
  53.  
  54. static char unsigned *pBits =0;
  55. static long Stride =0;
  56.  
  57. //****************************************************************************
  58. // Application entry point
  59.  
  60. int main()
  61. {
  62.     // Initialize the Mac
  63.     MaxApplZone();
  64.     MoreMasters();
  65.     InitGraf(&qd.thePort);
  66.     InitFonts();
  67.     FlushEvents(everyEvent, 0);
  68.     InitWindows();
  69.     InitMenus();
  70.     InitDialogs(0L);
  71.     InitCursor();
  72.  
  73.     // Check for Display Manager using Gestalt
  74.     long GestaltValue = 0;
  75.     long DisplayManagerVersion = 0;
  76.     Gestalt(gestaltDisplayMgrAttr, &GestaltValue);
  77.     if (GestaltValue & (1<<gestaltDisplayMgrPresent))
  78.         Gestalt(gestaltDisplayMgrVers, &DisplayManagerVersion);
  79.  
  80.     // If Display Manager 2.x is available, proceed
  81.     if (DisplayManagerVersion >= 0x00020000)
  82.         DemoMain();
  83.  
  84.     return 0;
  85. }
  86.  
  87. //****************************************************************************
  88. // Offscreen access
  89.  
  90. char unsigned *GetOffscreenBits(void)
  91. {
  92.     return pBits;
  93. }
  94.  
  95. long GetOffscreenStride(void)
  96. {
  97.     return Stride;
  98. }
  99.  
  100. int OffscreenLock(void)
  101. {
  102.     int ReturnValue = 0;
  103.  
  104.     pBits = 0;
  105.     Stride = 0;
  106.  
  107.     // Get the PixMap structure of the offscreen GWorld
  108.     PixMapHandle OffscreenPixMap = GetGWorldPixMap(pOffscreenGWorld);
  109.     if (OffscreenPixMap)
  110.     {
  111.         // Lock the PixMap memory and pull info off the PixMap
  112.         LockPixels(OffscreenPixMap);
  113.         pBits = (char unsigned *)GetPixBaseAddr(OffscreenPixMap);
  114.         Stride = (*OffscreenPixMap)->rowBytes & 0x3FFF;
  115.  
  116.         ReturnValue = 1;
  117.     }
  118.  
  119.     return ReturnValue;
  120. }
  121.  
  122. int OffscreenUnlock(void)
  123. {
  124.     int ReturnValue = 0;
  125.  
  126.     // Get the PixMap structure of the offscreen GWorld
  127.     PixMapHandle OffscreenPixMap = GetGWorldPixMap(pOffscreenGWorld);
  128.     if (OffscreenPixMap)
  129.     {
  130.         // Unlock the offscreen PixMap and reset the bits and stride
  131.         UnlockPixels(OffscreenPixMap);
  132.         pBits = 0;
  133.         Stride = 0;
  134.  
  135.         ReturnValue = 1;
  136.     }
  137.  
  138.     return ReturnValue;
  139. }
  140.  
  141. //****************************************************************************
  142. // Buffer swapping
  143.  
  144. void SwapBuffer(void)
  145. {
  146.     // Make sure ctSeed matches so we get a 1:1 blt, even though we
  147.     // have set up everything correctly when creating the GWorld in the
  148.     // first place.
  149.     // Basically, if QuickDraw knows the color tables are the same
  150.     // it will ignore any translation and just copy the bits. This
  151.     // is an extra trick to make sure it's satisfied.
  152.     PixMapHandle OffscreenPixMap = pOffscreenGWorld->portPixMap;
  153.     CTabHandle OffscreenCtab = (*OffscreenPixMap)->pmTable;
  154.  
  155.     PixMapHandle OnscreenPixMap = ((CWindowPtr)Window)->portPixMap;
  156.     CTabHandle OnscreenCtab = (*OnscreenPixMap)->pmTable;
  157.  
  158.     (*OffscreenCtab)->ctSeed = (*OnscreenCtab)->ctSeed;
  159.  
  160.     // Do the blt
  161.     CopyBits(&((GrafPtr)pOffscreenGWorld)->portBits,
  162.         &Window->portBits,
  163.         &Window->portRect, &Window->portRect,
  164.         srcCopy, 0);
  165. }
  166.  
  167. void SwapRect(int Left, int Top, int Right, int Bottom)
  168. {
  169.     // Make sure ctSeed matches so we get a 1:1 blt, as above
  170.     PixMapHandle OffscreenPixMap = pOffscreenGWorld->portPixMap;
  171.     CTabHandle OffscreenCtab = (*OffscreenPixMap)->pmTable;
  172.  
  173.     PixMapHandle OnscreenPixMap = ((CWindowPtr)Window)->portPixMap;
  174.     CTabHandle OnscreenCtab = (*OnscreenPixMap)->pmTable;
  175.  
  176.     (*OffscreenCtab)->ctSeed = (*OnscreenCtab)->ctSeed;
  177.  
  178.     Rect BltRect = { Top, Left, Bottom, Right };
  179.  
  180.     // Do the blt
  181.     CopyBits(&((GrafPtr)pOffscreenGWorld)->portBits,
  182.         &Window->portBits,
  183.         &BltRect, &BltRect,
  184.         srcCopy, 0);
  185. }
  186.  
  187. //****************************************************************************
  188. // Full Screen initialization
  189.  
  190. // This structure encapsulates the data sent to the Display Manager list
  191. // enumeration callback function. We fill in the desired values, pass this
  192. // on through the enumeration, and it fills in the csMode and csData info
  193. // we need.
  194. struct DisplayModeRequest
  195. {
  196.     // Returned values
  197.     unsigned short csMode;
  198.     unsigned long csData;
  199.  
  200.     // Provided values
  201.     long DesiredWidth;
  202.     long DesiredHeight;
  203.     long DesiredDepth;
  204. };
  205.  
  206. // This function filters through the display modes reported by the Display
  207. // Manager, looking for one that matches the requested resolution. The
  208. // userData pointer will point to a DisplayModeRequest structure.
  209. pascal void DisplayModeCallback(void* userData, DMListIndexType,
  210.     DMDisplayModeListEntryPtr pModeInfo)
  211. {
  212.     DisplayModeRequest *pRequest = (DisplayModeRequest*)userData;
  213.  
  214.     // Get timing info and make sure this is an OK display mode
  215.     VDTimingInfoRec TimingInfo = *(pModeInfo->displayModeTimingInfo);
  216.     if (TimingInfo.csTimingFlags & 1<<kModeValid)
  217.     {
  218.         // How many modes are being enumerated here?
  219.         unsigned long DepthCount =
  220.             pModeInfo->displayModeDepthBlockInfo->depthBlockCount;
  221.  
  222.         // Filter through each of the modes provided here
  223.         VDSwitchInfoRec *pSwitchInfo;
  224.         VPBlock *pVPBlockInfo;
  225.         for (short Count = 0; Count < DepthCount; ++Count)
  226.         {
  227.             // This provides the csMode and csData information
  228.             pSwitchInfo =
  229.                 pModeInfo->displayModeDepthBlockInfo->
  230.                 depthVPBlock[Count].depthSwitchInfo;
  231.  
  232.             // This tells us the resolution and pixel depth
  233.             pVPBlockInfo =
  234.                 pModeInfo->displayModeDepthBlockInfo->
  235.                 depthVPBlock[Count].depthVPBlock;
  236.  
  237.             if (pVPBlockInfo->vpPixelSize == pRequest->DesiredDepth &&
  238.                 pVPBlockInfo->vpBounds.right == pRequest->DesiredWidth &&
  239.                 pVPBlockInfo->vpBounds.bottom == pRequest->DesiredHeight)
  240.             {
  241.                 // Found a mode that matches the request!
  242.                 pRequest->csMode = pSwitchInfo->csMode;
  243.                 pRequest->csData = pSwitchInfo->csData;
  244.             }
  245.         }
  246.     }
  247. }
  248.  
  249. int BeginFullScreen(int Width, int Height, int Depth)
  250. {
  251.     // Hide the menu bar
  252.     StealMenuBar();
  253.  
  254.     // Create a window of the requested size
  255.     Rect WindowRect = { 0, 0, Height, Width };
  256.     Window = NewCWindow(0, &WindowRect, "\pFullScreen",
  257.         TRUE, plainDBox,
  258.         WindowPtr(-1), FALSE, 0);
  259.     if (!Window)
  260.         goto Failure;
  261.  
  262.     // Set up a palette with a gray wash
  263.     hPalette = NewPalette(256, 0, pmExplicit | pmAnimated, 0);
  264.     if (!hPalette)
  265.         goto Failure;
  266.  
  267.     RGBColor Color;
  268.     int i;
  269.     for (i=0; i<256; ++i)
  270.     {
  271.         Color.red= i << 8;
  272.         Color.green = i << 8;
  273.         Color.blue = i << 8;
  274.  
  275.         SetEntryColor(hPalette, i, &Color);
  276.     }
  277.  
  278.     // Force 0 and 255 to White and Black
  279.     SetEntryUsage(hPalette, 0, pmExplicit | pmAnimated | pmWhite, 0);
  280.     SetEntryUsage(hPalette, 255, pmExplicit | pmAnimated | pmBlack, 0);
  281.  
  282.     SetPalette(Window, hPalette, TRUE);
  283.  
  284.     // Store information about the current display settings
  285.     DisplayDevice = GetMainDevice();
  286.     if (!DisplayDevice)
  287.         goto Failure;
  288.  
  289.     csPreviousMode = -1;
  290.     csPreviousData = -1;
  291.  
  292.     VDSwitchInfoRec DisplayInfo;
  293.     OSErr MacError = DMGetDisplayMode(DisplayDevice, &DisplayInfo);
  294.     if (MacError != noErr)
  295.         goto Failure;
  296.  
  297.     csPreviousMode = DisplayInfo.csMode;
  298.     csPreviousData = DisplayInfo.csData;
  299.  
  300.     // Get the display ID for the main display
  301.     DisplayIDType DisplayID;
  302.     DMGetDisplayIDByGDevice(DisplayDevice, &DisplayID, FALSE);
  303.  
  304.     // Use it to get a list of available modes from the Display Manager
  305.     DMListIndexType DisplayModeCount = 0;
  306.     DMListType DisplayModeList;
  307.     MacError = DMNewDisplayModeList(DisplayID, 0, 0,
  308.         &DisplayModeCount, &DisplayModeList);
  309.     if (MacError != noErr)
  310.         goto Failure;
  311.  
  312.     // Create a callback function pointer to filter available modes
  313.     DMDisplayModeListIteratorUPP uppDisplayModeCallback =
  314.         NewDMDisplayModeListIteratorProc(DisplayModeCallback);
  315.     if (!uppDisplayModeCallback)
  316.     {
  317.         // Aborting - let go of the mode list
  318.         DMDisposeList(DisplayModeList);
  319.         goto Failure;
  320.     }
  321.  
  322.     // Go through the list, comparing each available mode with
  323.     // this mode request
  324.     DisplayModeRequest ModeRequest;
  325.     ModeRequest.csMode = -1;
  326.     ModeRequest.csData = -1;
  327.     ModeRequest.DesiredWidth = Width;
  328.     ModeRequest.DesiredHeight = Height;
  329.     ModeRequest.DesiredDepth = Depth;
  330.  
  331.     for (short Count = 0; Count < DisplayModeCount; ++Count)
  332.     {
  333.         DMGetIndexedDisplayModeFromList(DisplayModeList, Count,
  334.             0, uppDisplayModeCallback, (void*)&ModeRequest);
  335.     }
  336.  
  337.     // Done with the list
  338.     DMDisposeList(DisplayModeList);
  339.  
  340.     // Done with the callback
  341.     DisposeRoutineDescriptor(uppDisplayModeCallback);
  342.  
  343.     // If we found a mode fitting the request, switch to it!
  344.     if (ModeRequest.csMode == -1 || ModeRequest.csData == -1)
  345.         goto Failure;
  346.  
  347.     DisplayInfo.csMode = ModeRequest.csMode;
  348.     DisplayInfo.csData = ModeRequest.csData;
  349.  
  350.     unsigned long Mode = DisplayInfo.csMode;
  351.     MacError = DMSetDisplayMode(DisplayDevice,
  352.         DisplayInfo.csData, &Mode,
  353.         (unsigned long)&DisplayInfo,
  354.         0);
  355.     if (MacError != noErr)
  356.         goto Failure;
  357.  
  358.     // Create a matching GWorld using current device and window
  359.     CGrafPtr CurrentPort = (CWindowPtr)Window;
  360.     
  361.     PixMapHandle CurrentPixMap = CurrentPort->portPixMap;
  362.     CTabHandle ColorTable = (*CurrentPixMap)->pmTable;
  363.  
  364.     NewGWorld(&pOffscreenGWorld, (short)Depth,
  365.         &CurrentPort->portRect, ColorTable,
  366.         DisplayDevice, noNewDevice);
  367.     if (!pOffscreenGWorld)
  368.         goto Failure;
  369.  
  370.     // Success!
  371.     return 1;
  372.  
  373. Failure:
  374.     RestoreMenuBar();
  375.     return 0;
  376. }
  377.  
  378. //****************************************************************************
  379. // Full Screen clean-up
  380.  
  381. void EndFullScreen(void)
  382. {
  383.     if (Window)
  384.     {
  385.         DisposeWindow(Window);
  386.         Window = 0;
  387.     }
  388.     
  389.     if (pOffscreenGWorld)
  390.     {
  391.         DisposeGWorld(pOffscreenGWorld);
  392.         pOffscreenGWorld = 0;
  393.     }
  394.  
  395.     if (csPreviousMode != -1 && csPreviousData != -1)
  396.     {
  397.         // Set the display back to its starting place
  398.         VDSwitchInfoRec OriginalInfo;
  399.         OriginalInfo.csMode = csPreviousMode;
  400.         OriginalInfo.csData = csPreviousData;
  401.  
  402.         unsigned long Mode = csPreviousMode;
  403.         DMSetDisplayMode(DisplayDevice,
  404.             csPreviousData, &Mode,
  405.             (unsigned long)&OriginalInfo,
  406.             0);
  407.     }
  408.  
  409.     RestoreMenuBar();
  410. }
  411.  
  412. //****************************************************************************
  413. // Menu bar manipulation functions
  414.  
  415. static short _OldMBarHeight = 0;
  416. static RgnHandle _OldDesktopRgn = 0;
  417.  
  418. void StealMenuBar(void)
  419. {
  420.     RgnHandle DesktopRgn;
  421.  
  422.     if (_OldMBarHeight == 0)
  423.     {
  424.         // Get and copy the current gray region
  425.         DesktopRgn = LMGetGrayRgn();
  426.         _OldDesktopRgn = NewRgn();
  427.         CopyRgn(DesktopRgn, _OldDesktopRgn);
  428.         
  429.         // Fudge the menu bar height
  430.         _OldMBarHeight = GetMBarHeight();
  431.         LMSetMBarHeight(0);
  432.  
  433.         // Turn the gray into the old gray region plus the menu bar region
  434.         Rect MenuRect;
  435.         MenuRect.left = 0;
  436.         MenuRect.top = 0;
  437.         MenuRect.right = qd.screenBits.bounds.right;
  438.         MenuRect.bottom = _OldMBarHeight;
  439.         RgnHandle MenuRgn = NewRgn();
  440.         RectRgn(MenuRgn, &MenuRect);
  441.  
  442.         UnionRgn(_OldDesktopRgn, MenuRgn, DesktopRgn);
  443.         DisposeRgn(MenuRgn);
  444.     }
  445. }
  446.  
  447. void RestoreMenuBar(void)
  448. {
  449.     if (_OldMBarHeight && _OldDesktopRgn)
  450.     {
  451.         // Restore the menu bar height
  452.         LMSetMBarHeight(_OldMBarHeight);
  453.         _OldMBarHeight = 0;
  454.  
  455.         // Restore the old desktop region
  456.         CopyRgn(_OldDesktopRgn, LMGetGrayRgn());
  457.         DisposeRgn(_OldDesktopRgn);
  458.         _OldDesktopRgn = 0;
  459.         
  460.         // Redraw the menu bar
  461.         HiliteMenu(0);
  462.         DrawMenuBar();
  463.     }
  464. }
  465.  
  466. #endif // not _WINDOWS
  467.